package com.gx.smart.building.ui.swap.fragment

import android.content.Intent
import android.text.Editable
import android.text.TextWatcher
import android.view.View
import android.view.ViewGroup
import android.widget.AdapterView
import com.blankj.utilcode.util.KeyboardUtils
import com.blankj.utilcode.util.TimeUtils
import com.blankj.utilcode.util.ToastUtils
import com.gx.smart.building.R
import com.gx.smart.building.databinding.FragmentStartSwapBinding
import com.gx.smart.building.ui.common.fragment.UploadImageFragment
import com.gx.smart.building.ui.swap.WaitingSignActivity
import com.gx.smart.building.ui.swap.adapter.SwapDeviceAdapter
import com.gx.smart.building.ui.swap.adapter.SwapDeviceConfirmAdapter
import com.gx.smart.building.ui.swap.adapter.SwapDeviceStatusAdapter
import com.gx.smart.building.ui.swap.adapter.SwapRepairAdapter
import com.gx.smart.building.ui.swap.adapter.SwapWarningAdapter
import com.gx.smart.building.ui.swap.model.SaveSwapContentMessageEvent
import com.gx.smart.building.ui.swap.model.ScheduleTimeLabel
import com.gx.smart.building.ui.swap.viewmodel.StartSwapViewModel
import com.huishi.gx.ib.grpc.lib.ib.admin.schedule.v1.AppScheduleTime
import com.huishi.gx.ib.grpc.lib.ib.admin.schedule.v1.RecordContent
import com.huishi.gx.ib.grpc.lib.ib.admin.schedule.v1.RecordDto
import com.huishi.gx.ib.grpc.lib.ib.admin.schedule.v1.RecordFile
import com.mylhyl.circledialog.CircleDialog
import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode

class StartSwapFragment : UploadImageFragment<StartSwapViewModel>() {

    private lateinit var viewBinding: FragmentStartSwapBinding
    private lateinit var stateAdapter: SwapDeviceAdapter
    private val stateList: MutableList<RecordContent.Builder> = mutableListOf()
    private lateinit var recordAdapter: SwapDeviceStatusAdapter
    private val recordList: MutableList<RecordContent.Builder> = mutableListOf()
    private lateinit var eventAdapter: SwapDeviceConfirmAdapter
    private val eventList: MutableList<RecordContent.Builder> = mutableListOf()
    private val items: MutableList<ScheduleTimeLabel> = mutableListOf()
    private var addContent: RecordDto.Builder = RecordDto.newBuilder()
    private lateinit var workOrderAdapter: SwapRepairAdapter
    private lateinit var alarmAdapter: SwapWarningAdapter
    private val recordFileList: MutableList<RecordFile.Builder> = mutableListOf()

    companion object {
        fun newInstance() = StartSwapFragment()
    }


    override fun onBindLayout(): Int = R.layout.fragment_start_swap

    override fun getToolbarTitle(): String = ""

    override fun enableToolbar(): Boolean = false

    override fun enableStatusBar(): Boolean = false

    override fun onBindViewModel(): Class<StartSwapViewModel> = StartSwapViewModel::class.java

    override fun initContentView(root: ViewGroup) {
        viewBinding = FragmentStartSwapBinding.inflate(layoutInflater, root, true)
        viewBinding.remind.addTextChangedListener(object : TextWatcher {
            override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {}
            override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {}
            override fun afterTextChanged(s: Editable) {
                viewBinding.wordCount.text = s.length.toString() + "/200"
            }
        })
        KeyboardUtils.registerSoftInputChangedListener(requireActivity()) {
            if (KeyboardUtils.isSoftInputVisible(requireActivity())) {
                viewBinding.submitLayout.visibility = View.GONE
            } else {
                viewBinding.submitLayout.visibility = View.VISIBLE
            }
        }
        stateAdapter = SwapDeviceAdapter(requireContext(), stateList)
        viewBinding.deviceRecyclerView.adapter = stateAdapter
        recordAdapter = SwapDeviceStatusAdapter(requireContext(), recordList)
        viewBinding.deviceStatusRecyclerView.adapter = recordAdapter
        eventAdapter = SwapDeviceConfirmAdapter(requireContext(), eventList)
        viewBinding.deviceConfirmRecyclerView.adapter = eventAdapter
        workOrderAdapter = SwapRepairAdapter(requireContext())
        viewBinding.workOrderRecyclerView.adapter = workOrderAdapter
        alarmAdapter = SwapWarningAdapter(requireContext())
        viewBinding.alarmRecyclerView.adapter = alarmAdapter
        viewBinding.submit.setOnClickListener {
            submit()
        }
        viewModel.queryAppScheduleModel().observe(viewLifecycleOwner) { check ->
            if (check == 2) {
                selectContentOrHistory()
            } else {
                bindContent()
            }
        }
        registerEventBus()
    }

    override fun onDestroyView() {
        super.onDestroyView()
        unregisterEventBus()
    }

    private fun getRecord(item: RecordDto) {
        viewModel.queryAppScheduleContent(item.recordList.map { it.contentId })
            .observe(viewLifecycleOwner) { recordMap ->
                val newDataList: List<RecordContent> = recordAdapter.dataList.map {
                    val newItem = it.toBuilder()
                    newItem.contentValue = recordMap[it.contentId]
                    newItem.build()
                }.toList()
                recordAdapter.refresh(newDataList)
                recordAdapter.notifyDataSetChanged()
            }
    }

    private fun selectContentOrHistory() {
        CircleDialog.Builder()
            .setTitle("历史草稿")
            .setText("您确定要采用上次历史草稿吗？")
            .setPositive("确定") { bindHistory() }
            .setNegative("取消") { bindContent() }
            .show(requireActivity().supportFragmentManager)
    }

    private fun bindHistory() {
        viewModel.history
            .observe(viewLifecycleOwner) { item ->
                addContent = RecordDto.newBuilder(item)
                bindUI(item)
                viewModel.queryAppScheduleTimeListByUser(item.modelId).observe(viewLifecycleOwner) {
                    addScheduleData(it)
                }
            }
    }

    private fun bindContent() {
        viewModel.content.observe(viewLifecycleOwner) { item ->
            addContent = RecordDto.newBuilder(item)
            bindUI(item)
            viewModel.queryAppScheduleTimeListByUser(item.modelId).observe(viewLifecycleOwner) {
                addScheduleData(it)
            }
        }
    }

    private fun addScheduleData(data: List<AppScheduleTime>) {
        if (data.isNotEmpty()) {
            for (item in data) {
                items.add(
                    ScheduleTimeLabel(
                        item.scheduleId,
                        item.scheduleName, item.scheduleTimeId,
                        item.scheduleTimeName, item.floatTimeBegin,
                        item.floatTimeEnd
                    )
                )
            }
        }
    }

    override fun initData() {
        //如果模版请求失败就不让使用该功能
        viewModel.contentSuccess.observe(viewLifecycleOwner) { result ->
            if (!result) {
                requireActivity().finish()
            }
        }
        viewModel.uploadSuccess.observe(viewLifecycleOwner) {
            val uploadSuccess: Boolean = it.isSuccess
            val fileName: String = it.fileName
            if (uploadSuccess) {
                picList1.add(it)
            } else {
                displayFailImage1(fileName)
            }
        }
    }


    private fun bindUI(item: RecordDto) {
        viewBinding.organName.text = item.organName
        viewBinding.scheduleName.text = item.scheduleName
        viewBinding.scheduleName.setOnClickListener {
            selectScheduleName()
        }
        //2022-08-19 11:30-12:00
        val begin = TimeUtils.millis2String(item.floatTimeBegin, "yyyy-MM-dd HH:mm")
        val end = TimeUtils.millis2String(item.floatTimeEnd, "HH:mm")
        viewBinding.floatTimeBeginEnd.text = "$begin-$end"
        //交接内容
        stateList.addAll(item.stateList.map { it.toBuilder() })
        stateAdapter.addAll(item.stateList)
        recordList.addAll(item.recordList.map { it.toBuilder() })
        recordAdapter.addAll(item.recordList)
        //获取读数
        viewBinding.getRecord.setOnClickListener {
            getRecord(item)
        }
        eventList.addAll(item.eventList.map { it.toBuilder() })
        eventAdapter.addAll(item.eventList)
        //提醒事项
        viewBinding.remind.setText(item.remind ?: "")
        //关联事项
        if (item.workOrderContentCount == 0) {
            viewBinding.workOrderLabel.text = "维修工单：无"
        } else {
            workOrderAdapter.addAll(item.workOrderContentList)
        }
        if (item.alarmContentCount == 0) {
            viewBinding.alarmLabel.text = "报警记录：无"
        } else {
            alarmAdapter.addAll(item.alarmContentList)
        }
        //图片上传
        initAdapter1()
        viewBinding.attachmentRecyclerView.adapter = attachmentAdapter1
    }


    private fun submit() {
        updateAddContent()
        viewModel
            .insertAppScheduleRecord(addContent.build())
            .observe(viewLifecycleOwner) {
                val intent = Intent(requireActivity(), WaitingSignActivity::class.java)
                intent.putExtra("id", it)
                startActivity(intent)
                requireActivity().finish()
            }
    }

    private fun selectScheduleName() {
        CircleDialog.Builder()
            .setItems(items) { _: AdapterView<*>?, _: View?, position: Int, _: Long ->
                addContent.scheduleId = items[position].scheduleId
                addContent.scheduleName = items[position].scheduleName
                addContent.scheduleTimeId = items[position].scheduleTimeId
                addContent.scheduleTimeName = items[position].scheduleTimeName
                addContent.floatTimeBegin = items[position].floatTimeBegin
                addContent.floatTimeEnd = items[position].floatTimeEnd
                bindScheduleName(items[position])
                true
            }
            .setNegative("取消", null)
            .show(requireActivity().supportFragmentManager)
    }

    private fun bindScheduleName(item: ScheduleTimeLabel) {
        viewBinding.scheduleName.text = item.scheduleName
        //2022-08-19 11:30-12:00
        val begin = TimeUtils.millis2String(item.floatTimeBegin, "yyyy-MM-dd HH:mm")
        val end = TimeUtils.millis2String(item.floatTimeEnd, "HH:mm")
        viewBinding.floatTimeBeginEnd.text = "$begin-$end"
    }

    /**
     * 同步图片信息
     */
    private fun setImages() {
        uploadImageAttachment1()
        recordFileList.clear()
        //去除删除的图片
        picList1.filter {
            attachmentAdapter1.dataList.map { item -> item.fileName }.contains(it.fileName)
        }
            .forEach { item ->
                recordFileList.add(
                    RecordFile.newBuilder()
                        .setFileName(item.fileName)
                        .setFileUrl(item.path)
                        .setFileType(1)
                )
            }
    }

    override fun uploadTask1(fileName: String, file: ByteArray) {
        viewModel.uploadImage(fileName, file)
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    fun handleSaveSwapContentMessageEvent(event: SaveSwapContentMessageEvent) {
        if (event != null) {
            updateAddContent()
            showInitLoadView(true)
            viewModel.noteAppScheduleRecord(addContent.build())
                .observe(viewLifecycleOwner) {
                    showInitLoadView(false)
                    ToastUtils.showLong("保存草稿成功")
                    requireActivity().finish()
                }
        }
    }

    /**
     * 保存草稿和提交都需要更新数据
     */
    private fun updateAddContent() {
        //交接内容
        addContent.clearState()
        addContent.addAllState(stateList.map { it.build() })
        //读数记录
        addContent.clearRecord()
        addContent.addAllRecord(recordList.map { it.build() })
        //确认事项
        addContent.clearEvent()
        addContent.addAllEvent(eventList.map { it.build() })
        //提醒事项
        addContent.remind = viewBinding.remind.editableText.toString().trim()
        //上传图片
        addContent.clearFile()
        setImages()
        addContent.addAllFile(recordFileList.map { it.build() }.toList())
    }

}